package com.sinodata.ns.backup;

import jt.classic.system.ISystem;
import jt.classic.system.database.SystemDataSource;
import jt.classic.system.log.LogManager;
import jt.classic.system.user.UserManager;

import org.limp.basework.Table;
import org.limp.basework.analyzer.TableRegisterCenter;
import org.limp.basework.impl.DBTableImpl;
import org.limp.basework.tools.TableBuilder;

import org.limp.mine.DataTrimmer;
import org.limp.mine.DateTrimmer;

import java.sql.Connection;
import java.text.SimpleDateFormat;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;


/**
 * 数据备份定时器
 *
 * @author mido
 *
 */
public class DataBackupTimer {
    private Timer timer = new Timer();
    private long delay = 50000;
    private long period = 1800000;

    /**
     * 构造函数
     * @param delay 延时时间
     * @param period 间隔时间
     */
    public DataBackupTimer(long delay, long period) {
        if (delay > 0) {
            this.delay = delay;
        }

        if (period > 0) {
            this.period = period;
        }
    }

    /**
     * 启动任务计划
     */
    public void runTask() {
        System.out.println("system message: DataBackup task is running...");
        timer.schedule(new MyTask(), this.delay, this.period);
    }

    /**
     * 停止任务计划
     */
    public void stopTask() {
        System.out.println("system message: DataBackup task is cancelled...");
        timer.cancel();
    }

    /**
     * 任务接口实现类
     * @author mido
     *
     */
    private class MyTask extends TimerTask {
        public void run() {
            Calendar calendar = Calendar.getInstance();

            /*每月第一天*/
            int day = calendar.get(Calendar.DAY_OF_MONTH);

            /*每月第一天日期*/
            String date = DateTrimmer.getMonthFirstDay();

            Connection conn = null;

            /*是否存在需要备份的数据*/
            boolean hasMoreData = false;

            try {
                SystemDataSource ds = SystemDataSource.getInstance();
                conn = ds.getConnection();

                String sql = "SELECT ID FROM APP_NS_TRACK WHERE CTIME <= '" +
                    DateTrimmer.formatDateForVarchar(date) + "000000'";

                DataTrimmer trimmer = new DataTrimmer(conn);

                hasMoreData = trimmer.haveMoreData(sql);
            } catch (Exception ex) {
                ISystem.catchException(this, ex);
            } finally {
                SystemDataSource.closeConnection(conn);
            }

            /*可执行备份任务*/
            if (((day == 1) && hasMoreData)) {
            	SimpleDateFormat sdf = new SimpleDateFormat("yyyy");

                Calendar lastDate = Calendar.getInstance();
                lastDate.set(Calendar.DATE, 1); //设为当前月的1号  
                lastDate.add(Calendar.MONTH, -1); //减一个月，变为下月的1号  
            	
                /*上月所属年*/
                String year = sdf.format(lastDate.getTime());
                
                String lastMonth = DateTrimmer.getMonth(-1);
                String lastMonthLabel = lastMonth;

                if (lastMonth.length() == 1) {
                    lastMonthLabel = "0" + lastMonth;
                }

                TableRegisterCenter trc = TableRegisterCenter.getInstance();

                /*备份数据表名称*/
                String newTableName = "APP_NS_TRACK" + year + lastMonthLabel +
                    "01";

                /*操作成功标识*/
                boolean isOK = true;

                /*不存在备份表注册信息*/
                if (!trc.containsTable(newTableName)) {
                    Table table = trc.findTable("APP_NS_TRACK");

                    /*克隆备份表实例*/
                    Table newTable = ((DBTableImpl) table).cloneOther(newTableName,
                            year + "年" + lastMonth + "月 轨迹备份数据");

                    /*备份数据表不需要原主键,故将其删除*/
                    newTable.removeColumn("ID");

                    try {
                        /*生成新备份表注册文件*/
                        trc.setTable(newTable, "app_ns_trackbak.table");

                        SystemDataSource ds = SystemDataSource.getInstance();
                        conn = ds.getConnection();

                        /*创建新备份数据表*/
                        TableBuilder tb = new TableBuilder(conn);
                        tb.setSQLKintter(null);
                        tb.build(newTable);
                    } catch (Exception ex) {
                        isOK = false;
                        ISystem.catchException(this, ex);

                        /*删除表注册信息*/
                        if (trc.containsTable(newTable.getName())) {
                            try {
                                trc.removeTable(newTable.getName());
                            } catch (Exception ex1) {
                                ISystem.catchException(this, ex1);
                            }
                        }
                    } finally {
                        SystemDataSource.closeConnection(conn);
                    }
                }

                if (isOK) {
                    String sql = "INSERT INTO " + newTableName +
                        " (USERID,USERNAME,GROUPID,GROUPNAME,BD,BDNAME,LON,LAT,CTIME,GC) " +
                        "SELECT USERID,USERNAME,GROUPID,GROUPNAME,BD,BDNAME,LON,LAT,CTIME,GC " +
                        "FROM APP_NS_TRACK WHERE CTIME <= '" +
                        DateTrimmer.formatDateForVarchar(date) + "000000'";

                    sql += (";DELETE FROM APP_NS_TRACK WHERE CTIME <= '" +
                    DateTrimmer.formatDateForVarchar(date) + "000000'");

                    try {
                        SystemDataSource ds = SystemDataSource.getInstance();
                        conn = ds.getConnection();

                        DataTrimmer trimmer = new DataTrimmer(conn);
                        trimmer.executeBatch(sql);

                        LogManager lm = new LogManager(conn);

                        lm.log(UserManager.createGuestUser(), "localhost", "",
                            "", "backupTrack", "insert",
                            "backup data-track[" + year + "年" + lastMonth +
                            "月] ok.");

                        conn.commit();
                    } catch (Exception ex) {
                        ISystem.catchException(this, ex);

                        try {
                            conn.rollback();
                        } catch (Exception ex1) {
                            ISystem.catchException(this, ex1);
                        }
                    } finally {
                        SystemDataSource.closeConnection(conn);
                    }
                }
            }
        }
    }
}
